<template>
  <view class="component-popup">
    <!-- 底部弹窗 -->
    <view mode-class="fade"
          v-if="props.modelValue && props.type === 'bottom'">
      <view class="popup-bg" @click="maskClose">
        <view
          :class="[
            'popup-bottom',
            radius ? 'radius' : '',
          ]"
          @click.stop=""
        >
          <view v-if="props.isHeader" class="header">
            <view class="h-l" @click="handleClose">
              <text v-if="props.isCancel">取消</text>
              <slot name="left">
              </slot>
            </view>
            <view class="h-c">
              {{ props.title }}
            </view>
            <view class="h-r" @click="handleConfirm">
              <text class="main-color" v-if="props.isConfirm">确定</text>
              <slot name="right"></slot>
            </view>
          </view>
          <slot name="content"></slot>
          <view class="footer" v-if="props.isCancel" @click="handleClose">
            {{props.cancelText}}
          </view>
        </view>
      </view>
    </view>
    <!-- 居中弹窗 -->
    <view mode-class="fade"
          v-if="props.modelValue && props.type === 'center'">
      <view class="popup-bg" @click="maskClose">
        <view
          :class="[
            'popup-center',
            props.radius ? 'radius' : '',
          ]"
          @click.stop=""
        >
          <view class="content">
            <view class="title">
              {{ props.title }}
            </view>
            <view class="text" v-if="props.text">
              {{ props.text }}
            </view>
            <view>
              <slot name="content">
              </slot>
            </view>
          </view>
          <slot name="footer"></slot>
          <view class="bottom" v-if="props.isConfirm || props.isCancel">
            <view class="button cancel" v-if="props.isCancel" @click="handleClose">
              {{props.cancelText}}
            </view>
            <view class="button confirm main-color" v-if="props.isConfirm" @click="handleConfirm">
              {{props.confirmText}}
            </view>
          </view>
        </view>
      </view>
    </view>
  </view>
</template>
<script lang="ts">
export default {
  name: 'UPopup'
}
</script>
<script lang="ts" setup>
import { reactive, defineProps, toRefs, PropType } from 'vue'
// slot 自定义内容 #content
const props = defineProps({
  modelValue: {
    type: Boolean,
    default: false
  },
  // 弹窗类型
  type: {
    type: String as PropType<'center' | 'bottom'>,
    default: 'center'
  },
  // 判断是否有确认按钮
  isConfirm: {
    type: Boolean,
    default: true
  },
  // 判断是否有取消按钮
  isCancel: {
    type: Boolean,
    default: true
  },
  // 确定按钮的文字
  confirmText: {
    type: String,
    default: '确定'
  },
  // 取消按钮的文字
  cancelText: {
    type: String,
    default: '取消'
  },
  // 标题文字
  title: {
    type: String,
    default: '标题'
  },
  // 显示内容
  text: {
    type: String,
    default: ''
  },
  // 圆角
  radius: {
    type: Boolean,
    default: true
  },
  // 是否禁止提交直接关闭，当需校验输入内容时使用，在父组件关闭弹窗
  disableConfirmClose: {
    type: Boolean,
    default: false
  },
  // 是否使用蒙版关闭
  disbaleMaskClose: {
    type: Boolean,
    default: true
  },
  // 判断是否显示header
  isHeader: {
    type: Boolean,
    default: false
  }
})
const emit = defineEmits(['update:modelValue', 'cancel', 'confirm'])
const dialogMap = reactive({
  // 取消事件
  handleClose() {
    emit('update:modelValue', false)
    emit('cancel')
  },
  // 确认事件
  handleConfirm() {
    if (!props.disableConfirmClose) {
      emit('update:modelValue', false)
    }
    emit('cancel')
    emit('confirm')
  },
  // 蒙版关闭
  maskClose() {
    props.disbaleMaskClose && dialogMap.handleClose()
  }
})
const { handleClose, handleConfirm, maskClose } = toRefs(dialogMap)
</script>
<style lang="scss" scoped>
.component-popup {
  .popup-bg {
    position: fixed;
    z-index: 901;
    top: 0;
    height: 100vh;
    left: 0;
    width: 100vw;
    background-color: rgba(0,0,0,.5);
  }
  .popup-bottom {
    position: fixed;
    z-index: 902;
    bottom: 0;
    padding-bottom: env(safe-area-inset-bottom);
    left: 0;
    width: 100vw;
    background: var(--bg-light-color);
    &.radius {
      border-radius: 16rpx 16rpx 0 0;
    }
    .header {
      height: 88rpx;
      display: flex;
      justify-content: space-between;
      align-items: center;
      padding: 0 40rpx;
      line-height: 88rpx;
      font-size: 16px;
      .h-c {
        text-align: center;
        font-size: 16px;
        font-weight: 500;
        color: var(--text-color-1);
      }
    }
    .footer {
      height: 88rpx;
      text-align: center;
      font-size: 16px;
      line-height: 88rpx;
      color: var(--text-color-1);
    }
  }
  .popup-center {
    position: fixed;
    z-index: 902;
    top: 50%;
    left: 50%;
    transform: translate(-50%, -50%);
    width: 560rpx;
    background: var(--bg-light-color);
    box-shadow: 0px 16rpx 48rpx 0px rgba(0,0,0,0.16);
    &.radius {
      border-radius: 16rpx;
    }
    .content {
      padding: 40rpx 32rpx;
      .title {
        text-align: center;
        font-size: 16px;
        font-weight: 500;
        color: var(--text-color-1);
      }
      .text {
        color: var(--text-color-3);
        line-height: 20px;
        font-size: 14px;
        margin-top: 8rpx;
        text-align: center;
      }
    }
    .bottom {
      display: flex;
      height: 88rpx;
      border-top: 1rpx solid var(--line-color);
      .button {
        flex: 1;
        height: 88rpx;
        line-height: 88rpx;
        text-align: center;
        &:nth-of-type(2) {
          border-left: 1rpx solid var(--line-color);
        }
      }
    }
  }
  /*设置动画*/
  .fade-enter-active, .fade-leave-active {
    transition: opacity .3s ease;
  }

  .fade-enter-from,  .fade-leave-to {
    opacity: 0;
  }
  .up-enter-active, .up-leave-active {
    transition: all .3s ease;
  }

  .up-enter-from,  .up-leave-to {
    transform: translate(0, 100%);
  }
}
</style>
